#include <stdint.h>
#include "hypercalls.h"
#include "console.h"
#include "veth.h"

/*
  minimal MetaROUTER app example - main

  Copyright (C) 2013 Peter Lawrence

  All rights reserved.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License version 2.1, as
  published by the Free Software Foundation.  This program is
  distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  License for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with this program; if not, see <http://www.gnu.org/licenses/>.
*/

/*

Theory of operation:

As a single thread, we can simplify the implementation to simply poll the interrupt bit-field and act upon it

using the MIPS "wait" instruction ought to be a valid way to block in the absence of interrupts, 
but there is some instability on some versions of RouterOS on some platforms (it is a moving target at present)

At present, there are only two interrupts to service:
 IRQ1: virtual console
 IRQ3: virtual Ethernet
*/

int main(void)
{
	static volatile uint32_t virqs;

	/* tell host where interrupt bit-mask is kept */
	vm_setup_irqs((unsigned *) &virqs, 32);

	/*
	the exact purpose of vm_running is not yet clear to me
	for the time being, I loop until there isn't an error
	*/
	while (vm_running())
	{
//		asm("wait");
	}


	/* set up data queue for interoperating with virtual console */
	vm_init_console();

	/* set up data queue for interoperating with virtual Ethernet */
	vm_init_veth();

	for (;;)
	{
		/* service interrupts, if any */
		if (virqs)
		{
			/* service virtual Ethernet interrupt */
			if (virqs & (1UL << 3))
			{
				vm_service_veth();
			}

			/* service virtual console interrupt */
			if (virqs & (1UL << 1))
			{
				vm_service_console();
			}

			/* acknowledge any interrupts by clearing all bits */
			virqs = 0;
		}

//		asm("wait");
	}

}

